package io.kiki.sba.registry.server.clientInterface.providedata;

import io.kiki.sba.registry.common.model.constants.ValueConstants;
import io.kiki.sba.registry.common.model.metaserver.ProvideData;
import io.kiki.sba.registry.server.clientInterface.bootstrap.Config;
import io.kiki.sba.registry.server.shared.providedata.AbstractFetchSystemPropertyService;
import io.kiki.sba.registry.server.shared.providedata.SystemDataStorage;
import io.kiki.sba.registry.store.jdbc.convertor.AppRevisionDomainConvertor;
import io.kiki.sba.registry.util.JsonUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;


public class AppRevisionWriteSwitchService extends AbstractFetchSystemPropertyService<AppRevisionWriteSwitchService.SwitchStorage> {
    private static final Logger logger = LoggerFactory.getLogger(AppRevisionWriteSwitchService.class);
    @Autowired
    private Config config;

    public AppRevisionWriteSwitchService() {
        super(ValueConstants.APP_REVISION_WRITE_SWITCH_DATA_ID, new SwitchStorage(INIT_VERSION, new AppRevisionDomainConvertor.EnableConfig()));
    }

    @Override
    protected int getSystemPropertyIntervalMillis() {
        return config.getSystemPropertyIntervalMillis();
    }

    @Override
    protected boolean doProcess(SwitchStorage expect, ProvideData data) {
        final String switchString = ProvideData.toString(data);

        AppRevisionDomainConvertor.EnableConfig enableConfig = new AppRevisionDomainConvertor.EnableConfig();
        if (StringUtils.isNotBlank(switchString)) {
            try {
                enableConfig = JsonUtils.read(switchString, AppRevisionDomainConvertor.EnableConfig.class);
            } catch (Throwable e) {
                logger.error("Decode appRevision write switch failed", e);
                return false;
            }
        }
        SwitchStorage update = new SwitchStorage(data.getVersion(), enableConfig);
        if (!compareAndSet(expect, update)) {
            return false;
        }
        AppRevisionDomainConvertor.setEnableConfig(enableConfig);
        logger.info("Fetch appRevision write switch, prev={}, current={}", expect.enableConfig, switchString);
        return true;
    }

    protected static class SwitchStorage extends SystemDataStorage {
        protected final AppRevisionDomainConvertor.EnableConfig enableConfig;

        public SwitchStorage(long version, AppRevisionDomainConvertor.EnableConfig enableConfig) {
            super(version);
            this.enableConfig = enableConfig;
        }
    }
}
